package com.dongnao.network.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.Iterator;

/**
 * @author sjy
 * @date 2024年05月09日 18:30
 */
public class SocketChannelServer2 {

    private static ArrayList<SocketChannel> channels = new ArrayList<>();

    public static void main(String[] args) throws Exception {
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();//打开一个通道，默认是阻塞的
        serverSocketChannel.configureBlocking(false);//设置为非阻塞模式
        serverSocketChannel.socket().bind(new InetSocketAddress(8080));//绑定端口
        System.out.println("服务端启动");
        while (true) {
            //获取新tcp连接通道，非阻塞的，没有就返回null
            SocketChannel socketChannel = serverSocketChannel.accept();
            //tcp请求 读取/响应
            if (socketChannel != null) {
                System.out.println("收到新连接：" + socketChannel);
                socketChannel.configureBlocking(false);//默认是阻塞的，设置为false为非阻塞
                channels.add(socketChannel);
            } else {
                //没有新连接的情况下，就去处理现有连接的数据，处理完就删除
                Iterator<SocketChannel> iterator = channels.iterator();
                while (iterator.hasNext()) {
                    SocketChannel channel = iterator.next();
                    try {
                        ByteBuffer requestBuffer = ByteBuffer.allocate(1024);
                        //通道没有数据需要处理，那就待会再处理
                        if (channel.read(requestBuffer) == 0) {
                            continue;
                        }
                        //read非阻塞的
                        while (channel.isOpen() && channel.read(requestBuffer) != -1) {
                            //长连接下，需要手动判断数据有没有读取结束(此处做一个简单的判断：超过0字节)
                            if (requestBuffer.position() > 0) break;
                        }
                        if (requestBuffer.position() == 0) continue;
                        requestBuffer.flip();//转换为读模式
                        byte[] content = new byte[requestBuffer.limit()];
                        requestBuffer.get(content);
                        System.out.println("收到数据，来自：" + channel.getRemoteAddress());
                        System.out.println(new String(content));

                        //响应结果 200
                        String response = "HTTP/1.1 200 OK\r\n" + "Content-Length: 11\r\n\r\n" + "Hello World";
                        ByteBuffer buffer = ByteBuffer.wrap(response.getBytes());
                        while (buffer.hasRemaining()) {
                            channel.write(buffer);//非阻塞
                        }
                        iterator.remove();
                    } catch (IOException e) {
                        e.printStackTrace();
                        iterator.remove();
                    }
                }
            }
        }
    }
}
